home *** CD-ROM | disk | FTP | other *** search
Text File | 2000-10-06 | 80.0 KB | 2,706 lines | [TEXT/CWIE] |
- ///--------------------------------------------------------------------------------------
- // SpriteWorld.c
- //
- // Portions are copyright: © 1991-94 Tony Myles, All rights reserved worldwide.
- //
- // Description: implementation of the sprite world architecture
- ///--------------------------------------------------------------------------------------
-
- #ifndef __QUICKDRAW__
- #include <QuickDraw.h>
- #endif
-
- #ifndef __DEVICES__
- #include <Devices.h>
- #endif
-
- #ifndef __RETRACE__
- #include <Retrace.h>
- #endif
-
- #ifndef __MEMORY__
- #include <Memory.h>
- #endif
-
- #ifndef __GESTALT__
- #include <Gestalt.h>
- #endif
-
- #ifndef __TIMER__
- #include <Timer.h>
- #endif
-
- #ifndef __SWCOMMON__
- #include <SWCommonHeaders.h>
- #endif
-
- #ifndef __SPRITEWORLDUTILS__
- #include <SpriteWorldUtils.h>
- #endif
-
- #ifndef __SPRITEWORLD__
- #include <SpriteWorld.h>
- #endif
-
- #ifndef __SPRITELAYER__
- #include <SpriteLayer.h>
- #endif
-
- #ifndef __SPRITE__
- #include <Sprite.h>
- #endif
-
- #ifndef __SPRITEFRAME__
- #include <SpriteFrame.h>
- #endif
-
- #ifndef __BLITPIXIEINTERFACE__
- #include <BlitPixieInterface.h>
- #endif
-
- #ifndef __SCROLLING__
- #include <Scrolling.h>
- #endif
-
- #ifndef __TILING__
- #include <Tiling.h>
- #endif
-
- #include <BlitPixieHeader.h> // for BlitPixieGetProcessorType
-
- RgnHandle gSWCollisionSectRgn = NULL; // Initialized by SWEnterSpriteWorld
- RgnHandle gSWCollisionSpareRgn = NULL; // (used by SWRegionCollision )
-
- SpriteWorldPtr gSWCurrentSpriteWorld = NULL;
- SpritePtr gSWCurrentSpriteBeingDrawn = NULL;
-
- SpriteWorldPtr gSWCleanUpSpriteWorldP = NULL;
- CleanUpCallBackPtr gSWCleanUpCallBackP = NULL;
-
-
- ///--------------------------------------------------------------------------------------
- // SWEnterSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWEnterSpriteWorld(void)
- {
- OSErr err = noErr;
-
- gSWmmuMode = GetMMUMode();
-
- if ( !SWHasSystem7() )
- {
- err = kSystemTooOldErr;
- }
-
- BlitPixieGetProcessorType();
-
- if (gSWCollisionSectRgn == NULL && gSWCollisionSpareRgn == NULL)
- {
- gSWCollisionSectRgn = NewRgn();
- gSWCollisionSpareRgn = NewRgn();
- }
- else
- {
- err = kAlreadyCalledErr;
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteWorld(
- GDHandle mainGDH,
- SpriteWorldPtr *spriteWorldP,
- FramePtr windowFrameP,
- FramePtr backFrameP,
- FramePtr workFrameP,
- short maxDepth)
- {
- OSErr err;
- SpriteWorldPtr tempSpriteWorldP;
- PixMapHandle basePixMap;
-
-
- err = noErr;
- *spriteWorldP = NULL;
-
- tempSpriteWorldP = (SpriteWorldPtr)NewPtrClear((Size)sizeof(SpriteWorldRec));
- if (tempSpriteWorldP == NULL)
- err = MemError();
-
- if (err == noErr)
- {
- // Create the deadSpriteLayerP, but don't add it to the linked layer list
- err = SWCreateSpriteLayer(&tempSpriteWorldP->deadSpriteLayerP);
- if (err != noErr)
- DisposePtr((Ptr)tempSpriteWorldP);
- }
-
- if (err == noErr)
- {
- basePixMap = (**mainGDH).gdPMap;
- if ( maxDepth == 0 || (**basePixMap).pixelSize <= maxDepth )
- {
- tempSpriteWorldP->pixelDepth = (**basePixMap).pixelSize;
- }
- else
- {
- tempSpriteWorldP->pixelDepth = maxDepth;
- }
-
- tempSpriteWorldP->headSpriteLayerP = NULL;
- tempSpriteWorldP->tailSpriteLayerP = NULL;
-
- tempSpriteWorldP->mainSWGDH = mainGDH;
- tempSpriteWorldP->windowFrameP = windowFrameP;
- tempSpriteWorldP->extraBackFrameP = NULL;
- tempSpriteWorldP->backFrameP = backFrameP;
- tempSpriteWorldP->workFrameP = workFrameP;
- tempSpriteWorldP->offscreenDrawProc = SWStdWorldDrawProc;
- tempSpriteWorldP->screenDrawProc = SWStdWorldDrawProc;
- tempSpriteWorldP->doubleRectDrawProc = NULL;
- tempSpriteWorldP->postEraseCallBack = NULL;
- tempSpriteWorldP->postDrawCallBack = NULL;
- tempSpriteWorldP->windRect = windowFrameP->frameRect;
- tempSpriteWorldP->backRect = backFrameP->frameRect;
- tempSpriteWorldP->originalWindRect = windowFrameP->frameRect;
- tempSpriteWorldP->originalBackRect = backFrameP->frameRect;
-
- tempSpriteWorldP->headUpdateRectP = NULL;
-
- tempSpriteWorldP->scrollRectMoveBounds.left = 0;
- tempSpriteWorldP->scrollRectMoveBounds.top = 0;
- tempSpriteWorldP->scrollRectMoveBounds.right = 32767;
- tempSpriteWorldP->scrollRectMoveBounds.bottom = 32767;
- tempSpriteWorldP->horizScrollRectOffset = 0;
- tempSpriteWorldP->vertScrollRectOffset = 0;
- tempSpriteWorldP->horizScrollDelta = 0;
- tempSpriteWorldP->vertScrollDelta = 0;
- tempSpriteWorldP->worldMoveProc = NULL;
- tempSpriteWorldP->thereAreNonScrollingLayers = false;
-
- // Make sure visScrollRect is at 0,0 top-left corner
- tempSpriteWorldP->visScrollRect = windowFrameP->frameRect;
- OffsetRect(&tempSpriteWorldP->visScrollRect,
- -tempSpriteWorldP->visScrollRect.left,
- -tempSpriteWorldP->visScrollRect.top);
- tempSpriteWorldP->offscreenScrollRect = tempSpriteWorldP->visScrollRect;
- tempSpriteWorldP->oldVisScrollRect = tempSpriteWorldP->visScrollRect;
-
- tempSpriteWorldP->tileLayerArray = NULL;
- tempSpriteWorldP->tilingCache = NULL;
- tempSpriteWorldP->changedTiles = NULL;
- tempSpriteWorldP->tilingIsInitialized = false;
- tempSpriteWorldP->tilingIsOn = false;
- tempSpriteWorldP->numTilesChanged = 0;
- tempSpriteWorldP->tileChangeProc = NULL;
- tempSpriteWorldP->tileRectDrawProc = SWDrawTilesInRect;
- tempSpriteWorldP->tileMaskDrawProc = SWStdSpriteDrawProc;
- tempSpriteWorldP->partialMaskDrawProc = SWStdSpriteDrawProc;
-
- tempSpriteWorldP->frameHasOccurred = false;
- tempSpriteWorldP->fpsTimeInterval = 0L;
-
- tempSpriteWorldP->lastMicroseconds.hi = 0L;
- tempSpriteWorldP->lastMicroseconds.lo = 0L;
- tempSpriteWorldP->runningTimeCount = 0L;
-
- tempSpriteWorldP->vblTaskRec.hasVBLFired = true;
- tempSpriteWorldP->usingVBL = false;
-
- tempSpriteWorldP->backgroundColor.red = 0;
- tempSpriteWorldP->backgroundColor.green = 0;
- tempSpriteWorldP->backgroundColor.blue = 0;
- tempSpriteWorldP->backgroundValue = 0;
-
- SWClearStickyError();
-
- *spriteWorldP = tempSpriteWorldP;
- }
-
- return err;
- }
-
- ///--------------------------------------------------------------------------------------
- // SWCreateSpriteWorldFromWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWCreateSpriteWorldFromWindow(
- SpriteWorldPtr* spriteWorldP,
- CWindowPtr srcWindowP,
- Rect* worldRectP,
- Rect* offscreenRectP,
- short maxDepth)
- {
- OSErr err = noErr;
- FramePtr windowFrameP, backFrameP, workFrameP;
- Rect tempRect, globalRect, windRect;
- GDHandle mainGDH;
- PixMapHandle basePixMap;
- short depth;
-
-
- *spriteWorldP = NULL;
- windowFrameP = backFrameP = workFrameP = NULL;
-
- SetPort( (WindowPtr)srcWindowP );
-
- windRect = (worldRectP == NULL) ? srcWindowP->portRect : *worldRectP;
-
- globalRect = windRect;
- LocalToGlobal((Point *)&globalRect.top);
- LocalToGlobal((Point *)&globalRect.bottom);
-
-
- mainGDH = GetMaxDevice( &globalRect );
- SetGDevice( mainGDH );
- basePixMap = (**mainGDH).gdPMap;
- if ( maxDepth == 0 || (**basePixMap).pixelSize <= maxDepth )
- {
- depth = (**basePixMap).pixelSize;
- }
- else
- {
- depth = maxDepth;
- }
-
- if ( srcWindowP->portVersion < (short)0xC000 )
- {
- err = kNotCWindowErr;
- }
-
- // If a custom offscreenRect has been requested, use it instead.
- if (offscreenRectP == NULL)
- tempRect = windRect;
- else
- tempRect = *offscreenRectP;
-
- // offset Rect to (0,0) for back and work frames
- OffsetRect(&tempRect, -tempRect.left, -tempRect.top);
-
- if (err == noErr)
- {
- // create window frame
- err = SWCreateWindowFrame(srcWindowP, &windowFrameP, &windRect, tempRect.bottom);
- }
-
- if (err == noErr)
- {
- // create back drop frame
- err = SWCreateFrame(mainGDH, &backFrameP, &tempRect, depth, kCreateGWorld);
- }
-
- if (err == noErr)
- {
- // create work frame
- err = SWCreateFrame(mainGDH, &workFrameP, &tempRect, depth, kCreateGWorld);
- }
-
-
- if (err == noErr)
- {
- // create sprite world
- err = SWCreateSpriteWorld(mainGDH, spriteWorldP, windowFrameP,
- backFrameP, workFrameP, maxDepth);
- }
-
- if (err != noErr)
- {
- // an error occurred so dispose of anything we managed to create
-
- if (windowFrameP != NULL)
- {
- SWDisposeWindowFrame(&windowFrameP);
- }
-
- if (backFrameP != NULL)
- {
- SWDisposeFrame(&backFrameP);
- }
-
- if (workFrameP != NULL)
- {
- SWDisposeFrame(&workFrameP);
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWDisposeSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWDisposeSpriteWorld(
- SpriteWorldPtr *spriteWorldPP)
- {
- SpriteWorldPtr spriteWorldP = *spriteWorldPP;
- SpriteLayerPtr curLayerP;
- SpritePtr curSpriteP;
-
-
- if (spriteWorldP != NULL)
- {
- SWUnlockSpriteWorld(spriteWorldP);
-
- while ((curLayerP = SWGetNextSpriteLayer(spriteWorldP, NULL)) != NULL)
- {
- // dispose of each sprite in the layer
- while ((curSpriteP = SWGetNextSprite(curLayerP, NULL)) != NULL)
- {
- SWRemoveSprite(curSpriteP);
- SWDisposeSprite(&curSpriteP);
- }
-
- // dispose of each layer in the spriteWorld
- SWRemoveSpriteLayer(spriteWorldP, curLayerP);
- SWDisposeSpriteLayer(&curLayerP);
- }
-
- SWDisposeAllSpritesInLayer(spriteWorldP->deadSpriteLayerP);
- SWDisposeSpriteLayer(&spriteWorldP->deadSpriteLayerP);
-
- SWDisposeFrame(&spriteWorldP->backFrameP);
- SWDisposeFrame(&spriteWorldP->workFrameP);
- SWDisposeFrame(&spriteWorldP->extraBackFrameP);
-
- SWDisposeWindowFrame(&spriteWorldP->windowFrameP);
-
- SWExitTiling(spriteWorldP);
- SWSyncSpriteWorldToVBL(spriteWorldP, false);
-
- DisposePtr((Ptr)spriteWorldP);
- *spriteWorldPP = NULL; // Set original pointer to NULL
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWExitSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWExitSpriteWorld(void)
- {
- if (gSWCollisionSectRgn != NULL)
- DisposeRgn(gSWCollisionSectRgn);
- if (gSWCollisionSpareRgn != NULL)
- DisposeRgn(gSWCollisionSpareRgn);
-
- gSWCollisionSectRgn = NULL;
- gSWCollisionSpareRgn = NULL;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAddSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAddSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr newSpriteLayerP)
- {
- SpriteLayerPtr tailSpriteLayerP = spriteWorldP->tailSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if (tailSpriteLayerP != NULL)
- tailSpriteLayerP->nextSpriteLayerP = newSpriteLayerP;
- else
- spriteWorldP->headSpriteLayerP = newSpriteLayerP;
-
- newSpriteLayerP->prevSpriteLayerP = tailSpriteLayerP;
- newSpriteLayerP->nextSpriteLayerP = NULL;
-
- // make the new layer the tail
- spriteWorldP->tailSpriteLayerP = newSpriteLayerP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRemoveSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRemoveSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr oldSpriteLayerP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- // is there a next layer?
- if (oldSpriteLayerP->nextSpriteLayerP != NULL)
- {
- // link the next layer to the prev layer
- oldSpriteLayerP->nextSpriteLayerP->prevSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
- }
- else
- {
- // make the prev layer the tail
- spriteWorldP->tailSpriteLayerP = oldSpriteLayerP->prevSpriteLayerP;
- }
-
- // is there a prev layer?
- if (oldSpriteLayerP->prevSpriteLayerP != NULL)
- {
- // link the prev layer to the next layer
- oldSpriteLayerP->prevSpriteLayerP->nextSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
- }
- else
- {
- // make the next layer the head
- spriteWorldP->headSpriteLayerP = oldSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSwapSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSwapSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr srcSpriteLayerP,
- SpriteLayerPtr dstSpriteLayerP)
- {
- register SpriteLayerPtr swapSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(srcSpriteLayerP != NULL && dstSpriteLayerP != NULL);
-
- // Do nothing if the sprite layers are the same
- if (srcSpriteLayerP == dstSpriteLayerP)
- return;
-
- // adjacent Layers are a special case
- if ( srcSpriteLayerP->nextSpriteLayerP == dstSpriteLayerP ||
- dstSpriteLayerP->nextSpriteLayerP == srcSpriteLayerP )
- {
- if ( srcSpriteLayerP->nextSpriteLayerP == dstSpriteLayerP )
- {
- if ( srcSpriteLayerP->prevSpriteLayerP != NULL )
- (srcSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP = dstSpriteLayerP;
- if ( dstSpriteLayerP->nextSpriteLayerP != NULL )
- (dstSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP = srcSpriteLayerP;
-
- dstSpriteLayerP->prevSpriteLayerP = srcSpriteLayerP->prevSpriteLayerP;
- srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP->nextSpriteLayerP;
-
- dstSpriteLayerP->nextSpriteLayerP = srcSpriteLayerP;
- srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP;
- }
- else
- {
- if ( dstSpriteLayerP->prevSpriteLayerP != NULL )
- (dstSpriteLayerP->prevSpriteLayerP)->nextSpriteLayerP = srcSpriteLayerP;
- if ( srcSpriteLayerP->nextSpriteLayerP != NULL )
- (srcSpriteLayerP->nextSpriteLayerP)->prevSpriteLayerP = dstSpriteLayerP;
-
- srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP->prevSpriteLayerP;
- dstSpriteLayerP->nextSpriteLayerP = srcSpriteLayerP->nextSpriteLayerP;
-
- srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP;
- dstSpriteLayerP->prevSpriteLayerP = srcSpriteLayerP;
- }
- }
- else
- {
- if (srcSpriteLayerP->prevSpriteLayerP != NULL)
- srcSpriteLayerP->prevSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP;
- if (dstSpriteLayerP->prevSpriteLayerP != NULL)
- dstSpriteLayerP->prevSpriteLayerP->nextSpriteLayerP = srcSpriteLayerP;
- if (srcSpriteLayerP->nextSpriteLayerP != NULL)
- srcSpriteLayerP->nextSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP;
- if (dstSpriteLayerP->nextSpriteLayerP != NULL)
- dstSpriteLayerP->nextSpriteLayerP->prevSpriteLayerP = srcSpriteLayerP;
-
- swapSpriteLayerP = srcSpriteLayerP->nextSpriteLayerP;
- srcSpriteLayerP->nextSpriteLayerP = dstSpriteLayerP->nextSpriteLayerP;
- dstSpriteLayerP->nextSpriteLayerP = swapSpriteLayerP;
-
- swapSpriteLayerP = srcSpriteLayerP->prevSpriteLayerP;
- srcSpriteLayerP->prevSpriteLayerP = dstSpriteLayerP->prevSpriteLayerP;
- dstSpriteLayerP->prevSpriteLayerP = swapSpriteLayerP;
- }
-
- if (srcSpriteLayerP->nextSpriteLayerP == NULL)
- {
- spriteWorldP->tailSpriteLayerP = srcSpriteLayerP;
- }
- else if (srcSpriteLayerP->prevSpriteLayerP == NULL)
- {
- spriteWorldP->headSpriteLayerP = srcSpriteLayerP;
- }
-
- if (dstSpriteLayerP->nextSpriteLayerP == NULL)
- {
- spriteWorldP->tailSpriteLayerP = dstSpriteLayerP;
- }
- else if (dstSpriteLayerP->prevSpriteLayerP == NULL)
- {
- spriteWorldP->headSpriteLayerP = dstSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWGetNextSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC SpriteLayerPtr SWGetNextSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr curSpriteLayerP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- return (curSpriteLayerP == NULL) ?
- spriteWorldP->headSpriteLayerP :
- curSpriteLayerP->nextSpriteLayerP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWLockSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWLockSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- SpriteLayerPtr curSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- SWLockWindowFrame(spriteWorldP->windowFrameP);
- SWLockFrame(spriteWorldP->workFrameP);
- SWLockFrame(spriteWorldP->backFrameP);
- if (spriteWorldP->extraBackFrameP != NULL)
- SWLockFrame(spriteWorldP->extraBackFrameP);
-
- SWLockTiles(spriteWorldP);
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- while (curSpriteLayerP != NULL)
- {
- SWLockSpriteLayer(curSpriteLayerP);
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUnlockSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUnlockSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- SpriteLayerPtr curSpriteLayerP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- SWUnlockWindowFrame(spriteWorldP->windowFrameP);
- SWUnlockFrame(spriteWorldP->backFrameP);
- SWUnlockFrame(spriteWorldP->workFrameP);
- if (spriteWorldP->extraBackFrameP != NULL)
- SWUnlockFrame(spriteWorldP->extraBackFrameP);
-
- SWUnlockTiles(spriteWorldP);
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- while (curSpriteLayerP != NULL)
- {
- SWUnlockSpriteLayer(curSpriteLayerP);
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWSetPortToBackground
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToBackground(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- SWSetPortToFrame( spriteWorldP->backFrameP );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPortToWorkArea
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToWorkArea(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- SWSetPortToFrame( spriteWorldP->workFrameP );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPortToWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPortToWindow(
- SpriteWorldPtr spriteWorldP)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- SWSetPortToFrame( spriteWorldP->windowFrameP );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldOffscreenDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetSpriteWorldOffscreenDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(drawProc != NULL);
-
- #if SW_PPC
- if (drawProc == BlitPixieAllBitRectDrawProc)
- err = k68kOnlyErr;
- #endif
-
- if (spriteWorldP->pixelDepth < 8)
- {
- if ( drawProc == BlitPixieRectDrawProc )
- err = kWrongDepthErr;
- }
-
- if ( err == noErr )
- spriteWorldP->offscreenDrawProc = drawProc;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldScreenDrawProc
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSetSpriteWorldScreenDrawProc(
- SpriteWorldPtr spriteWorldP,
- DrawProcPtr drawProc)
- {
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(drawProc != NULL);
-
- #if SW_PPC
- if (drawProc == BlitPixieAllBitRectDrawProc)
- err = k68kOnlyErr;
- #endif
-
- if ( (*spriteWorldP->windowFrameP->framePort->portPixMap)->pixelSize < 8 ||
- (*spriteWorldP->windowFrameP->framePort->portPixMap)->pixelSize !=
- spriteWorldP->pixelDepth )
- {
- if ( drawProc == BlitPixieRectDrawProc )
- err = kWrongDepthErr;
- }
-
- if ( err == noErr )
- spriteWorldP->screenDrawProc = drawProc;
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPostEraseCallBack
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPostEraseCallBack(
- SpriteWorldPtr spriteWorldP,
- CallBackPtr callBack)
- {
- spriteWorldP->postEraseCallBack = callBack;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetPostDrawCallBack
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetPostDrawCallBack(
- SpriteWorldPtr spriteWorldP,
- CallBackPtr callBack)
- {
- spriteWorldP->postDrawCallBack = callBack;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetSpriteWorldMaxFPS
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetSpriteWorldMaxFPS(
- SpriteWorldPtr spriteWorldP,
- short framesPerSec)
- {
- SW_ASSERT(spriteWorldP != NULL);
-
- // is framesPerSec a valid value?
- if (framesPerSec > 0 && framesPerSec <= 1000 )
- {
- spriteWorldP->fpsTimeInterval = 1000/framesPerSec;
- }
- // framesPerSec is an "ignore it" value.
- else
- {
- spriteWorldP->fpsTimeInterval = 0;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetBackgroundColor
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetBackgroundColor(
- SpriteWorldPtr spriteWorldP,
- RGBColor *color)
- {
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->workFrameP != NULL);
-
- spriteWorldP->backgroundColor = *color;
- spriteWorldP->backgroundValue = SWGetValueFromColor( spriteWorldP->workFrameP, color );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWStdWorldClearDrawProc - calls RGBBackColor and EraseRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWStdWorldClearDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- #pragma unused(srcFrameP,srcRect)
- Rect dstCopyBitsRect = *dstRect;
-
- // clip off the top
- if (dstCopyBitsRect.top < dstFrameP->frameRect.top)
- {
- dstCopyBitsRect.top = dstFrameP->frameRect.top;
- if (dstCopyBitsRect.top >= dstCopyBitsRect.bottom) return;
- }
- // clip off the bottom
- if (dstCopyBitsRect.bottom > dstFrameP->frameRect.bottom)
- {
- dstCopyBitsRect.bottom = dstFrameP->frameRect.bottom;
- if (dstCopyBitsRect.bottom <= dstCopyBitsRect.top) return;
- }
- // clip off the left
- if (dstCopyBitsRect.left < dstFrameP->frameRect.left)
- {
- dstCopyBitsRect.left = dstFrameP->frameRect.left;
- if (dstCopyBitsRect.left >= dstCopyBitsRect.right)
- return;
- }
- // clip off the right
- if (dstCopyBitsRect.right > dstFrameP->frameRect.right)
- {
- dstCopyBitsRect.right = dstFrameP->frameRect.right;
- if (dstCopyBitsRect.right <= dstCopyBitsRect.left) return;
- }
-
- SW_ASSERT( gSWCurrentSpriteWorld != NULL );
-
- RGBBackColor( &gSWCurrentSpriteWorld->backgroundColor );
- EraseRect( &dstCopyBitsRect );
- BackColor(whiteColor);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWStdWorldDrawProc - calls CopyBits.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWStdWorldDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- Rect srcCopyBitsRect = *srcRect;
- Rect dstCopyBitsRect = *dstRect;
-
- // clip off the top
- if (dstCopyBitsRect.top < dstFrameP->frameRect.top)
- {
- srcCopyBitsRect.top += dstFrameP->frameRect.top - dstCopyBitsRect.top;
- dstCopyBitsRect.top = dstFrameP->frameRect.top;
- if (dstCopyBitsRect.top >= dstCopyBitsRect.bottom) return;
- }
- // clip off the bottom
- if (dstCopyBitsRect.bottom > dstFrameP->frameRect.bottom)
- {
- srcCopyBitsRect.bottom -= dstCopyBitsRect.bottom - dstFrameP->frameRect.bottom;
- dstCopyBitsRect.bottom = dstFrameP->frameRect.bottom;
- if (dstCopyBitsRect.bottom <= dstCopyBitsRect.top) return;
- }
- // clip off the left
- if (dstCopyBitsRect.left < dstFrameP->frameRect.left)
- {
- srcCopyBitsRect.left += dstFrameP->frameRect.left - dstCopyBitsRect.left;
- dstCopyBitsRect.left = dstFrameP->frameRect.left;
- if (dstCopyBitsRect.left >= dstCopyBitsRect.right)
- return;
- }
- // clip off the right
- if (dstCopyBitsRect.right > dstFrameP->frameRect.right)
- {
- srcCopyBitsRect.right -= dstCopyBitsRect.right - dstFrameP->frameRect.right;
- dstCopyBitsRect.right = dstFrameP->frameRect.right;
- if (dstCopyBitsRect.right <= dstCopyBitsRect.left) return;
- }
-
- CopyBits(
- (BitMap*)srcFrameP->framePix,
- (BitMap*)dstFrameP->framePix,
- &srcCopyBitsRect,
- &dstCopyBitsRect,
- srcCopy, NULL);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWInterlacedCopyBitsDrawProc - does interlaced CopyBits if interlacing is on
- //
- // thanks to George Warner and Steve Ramsey for the code this is based on.
- //
- // Note: This is a hack, and might break in the future.
- // It does not honor the clipRgn or visRgn of the dest port,
- // and disables any hardware acceleration for CopyBits.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWInterlacedCopyBitsDrawProc(
- FramePtr srcFrameP,
- FramePtr dstFrameP,
- Rect* srcRect,
- Rect* dstRect)
- {
- PixMap srcMap = *srcFrameP->framePix;
- PixMap dstMap = *dstFrameP->framePix;
- Rect srcCopyBitsRect = *srcRect;
- Rect dstCopyBitsRect = *dstRect;
- UInt32 srcRowBytes, dstRowBytes;
- SInt32 sourceTopShift, destTopShift;
-
- // clip off the top
- if (dstCopyBitsRect.top < dstFrameP->frameRect.top)
- {
- srcCopyBitsRect.top += dstFrameP->frameRect.top - dstCopyBitsRect.top;
- dstCopyBitsRect.top = dstFrameP->frameRect.top;
- if (dstCopyBitsRect.top >= dstCopyBitsRect.bottom) return;
- }
- // clip off the bottom
- if (dstCopyBitsRect.bottom > dstFrameP->frameRect.bottom)
- {
- srcCopyBitsRect.bottom -= dstCopyBitsRect.bottom - dstFrameP->frameRect.bottom;
- dstCopyBitsRect.bottom = dstFrameP->frameRect.bottom;
- if (dstCopyBitsRect.bottom <= dstCopyBitsRect.top) return;
- }
- // clip off the left
- if (dstCopyBitsRect.left < dstFrameP->frameRect.left)
- {
- srcCopyBitsRect.left += dstFrameP->frameRect.left - dstCopyBitsRect.left;
- dstCopyBitsRect.left = dstFrameP->frameRect.left;
- if (dstCopyBitsRect.left >= dstCopyBitsRect.right)
- return;
- }
- // clip off the right
- if (dstCopyBitsRect.right > dstFrameP->frameRect.right)
- {
- srcCopyBitsRect.right -= dstCopyBitsRect.right - dstFrameP->frameRect.right;
- dstCopyBitsRect.right = dstFrameP->frameRect.right;
- if (dstCopyBitsRect.right <= dstCopyBitsRect.left) return;
- }
-
- if ( dstFrameP->interlacingIsOn )
- {
- // Get the original bytes per row (ignore top two flag bits)
- srcRowBytes = srcMap.rowBytes & 0x3FFF;
- dstRowBytes = dstMap.rowBytes & 0x3FFF;
-
- // back up 2 rows
- //
- // This prevents QuickDraw from using an accelerated (hardware)
- // blitter that's optimized to go directly to VRAM (which might ignore
- // our hacked rowBytes value). Most of these accelerators compare base
- // addresses against their VRAM base to determine when they can
- // accelerate. I'm just messing up this compare.
- //
- // Backing up two full rows ensures that alignment stays the same and
- // that the even/odd relationships of the bounding Rects and blit Rects
- // stays the same.
- {
- srcMap.baseAddr -= (srcRowBytes + srcRowBytes);
- srcMap.bounds.top -= 2;
- srcMap.bounds.bottom -= 2;
-
- dstMap.baseAddr -= (dstRowBytes + dstRowBytes);
- dstMap.bounds.top -= 2;
- dstMap.bounds.bottom -= 2;
- }
-
- // flips whether even or odd scanlines are being drawn this frame
- if (!dstFrameP->skipOddLines) // i.e. we're drawing the odd lines
- {
- // Skip first line if it is even
- if ( !((dstCopyBitsRect.top - dstFrameP->frameRect.top) & 1 ))
- {
- srcCopyBitsRect.top++;
- dstCopyBitsRect.top++;
- }
-
- // This bit of adjustment is required to ensure that we're going
- // to be working with the right set of scanlines. Otherwise, once
- // the rowBytes have doubled, we would have no way of getting at
- // the "in-between" scanlines.
- srcMap.baseAddr += srcRowBytes;
- dstMap.baseAddr += dstRowBytes;
-
- srcCopyBitsRect.top--;
- dstCopyBitsRect.top--;
-
- // Adjust the blit Rect sizes to eliminate rounding errors that
- // can be introduced if the Rect height is odd. For the odd scanline
- // pass we force the adjusted Rect height to be floor'ed.
- if ((srcCopyBitsRect.bottom - srcCopyBitsRect.top) & 1)
- srcCopyBitsRect.bottom--;
-
- if ((dstCopyBitsRect.bottom - dstCopyBitsRect.top) & 1)
- dstCopyBitsRect.bottom--;
- }
- else // i.e. we're drawing the even lines
- {
- // Skip first line if it is odd
- if ( (dstCopyBitsRect.top - dstFrameP->frameRect.top) & 1 )
- {
- srcCopyBitsRect.top++;
- dstCopyBitsRect.top++;
- }
-
- // Adjust the blit Rect sizes to eliminate rounding errors that
- // can be introduced if the Rect height is odd. For the even
- // scanline pass we force the adjusted Rect height to be ceiling'ed.
- if ((srcCopyBitsRect.bottom - srcCopyBitsRect.top) & 1)
- srcCopyBitsRect.bottom++;
-
- if ((dstCopyBitsRect.bottom - dstCopyBitsRect.top) & 1)
- dstCopyBitsRect.bottom++;
- }
-
- // Define vertical shift values. Vertical shifting may be necessary if
- // a rounding error gets introduced in the coming calculations. Both the
- // srcPixMapP/destPixMapP rectangles and the baseAddress must be
- // shifted. Note that this would not be necessary if the Rects to be
- // blitted were restricted to even top values.
- sourceTopShift = (srcCopyBitsRect.top - srcMap.bounds.top) & 1;
- destTopShift = (dstCopyBitsRect.top - dstMap.bounds.top) & 1;
-
- if (sourceTopShift)
- srcMap.baseAddr -= srcRowBytes;
-
- if (destTopShift)
- dstMap.baseAddr -= dstRowBytes;
-
- // scale the source rect to reflect the new rowBytes value
- srcCopyBitsRect.bottom = (srcCopyBitsRect.bottom - srcMap.bounds.top) >> 1;
- srcCopyBitsRect.top = (srcCopyBitsRect.top - srcMap.bounds.top) >> 1;
-
- // scale the source PixMap bounds to reflect the new rowBytes value
- srcMap.bounds.top >>= 1;
- srcMap.bounds.bottom >>= 1;
-
- // scale the dest rect to reflect the new rowBytes value
- dstCopyBitsRect.bottom = (dstCopyBitsRect.bottom - dstMap.bounds.top) >> 1;
- dstCopyBitsRect.top = (dstCopyBitsRect.top - dstMap.bounds.top) >> 1;
-
- // scale the dest PixMap bounds to reflect the new rowBytes value
- dstMap.bounds.top >>= 1;
- dstMap.bounds.bottom >>= 1;
-
- // translate the source rect to reflect a change in the srcMap bounds origin
- srcCopyBitsRect.bottom += (srcMap.bounds.top + sourceTopShift);
- srcCopyBitsRect.top += (srcMap.bounds.top + sourceTopShift);
-
- // translate the dest rect to reflect a change in the destMap bounds origin
- dstCopyBitsRect.bottom += (dstMap.bounds.top + destTopShift);
- dstCopyBitsRect.top += (dstMap.bounds.top + destTopShift);
-
- srcCopyBitsRect.bottom += sourceTopShift;
- srcCopyBitsRect.top += sourceTopShift;
- dstCopyBitsRect.bottom += sourceTopShift;
- dstCopyBitsRect.top += sourceTopShift;
-
- srcMap.bounds.bottom += 1;
- dstMap.bounds.bottom += 1;
-
- // double source rowBytes (keep the top two flag bits)
- srcRowBytes += srcRowBytes;
- srcMap.rowBytes = (srcMap.rowBytes & 0xC000) | (srcRowBytes & 0x3FFF);
-
- // double destination rowBytes (keep the top two flag bits)
- dstRowBytes += dstRowBytes;
- dstMap.rowBytes = (dstMap.rowBytes & 0xC000) | (dstRowBytes & 0x3FFF);
-
- if (srcCopyBitsRect.top >= srcCopyBitsRect.bottom) return;
- if (dstCopyBitsRect.top >= dstCopyBitsRect.bottom) return;
-
- // and finally call (software) CopyBits to do the interlaced blit
- CopyBits(
- (BitMap*)&srcMap,
- (BitMap*)&dstMap,
- &srcCopyBitsRect,
- &dstCopyBitsRect,
- srcCopy, NULL);
- }
- else
- {
- CopyBits(
- (BitMap*)srcFrameP->framePix,
- (BitMap*)dstFrameP->framePix,
- &srcCopyBitsRect,
- &dstCopyBitsRect,
- srcCopy, NULL);
- }
- }
-
-
-
- ///--------------------------------------------------------------------------------------
- // SWCopyBackgroundToWorkArea
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCopyBackgroundToWorkArea(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- SWSetPortToFrame( spriteWorldP->workFrameP );
-
- // Copy the background frame into the work area
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &spriteWorldP->backFrameP->frameRect,
- &spriteWorldP->workFrameP->frameRect);
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWChangeWorldRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWChangeWorldRect(
- SpriteWorldPtr spriteWorldP,
- Rect* newWorldRectP,
- Boolean changeOffscreenAreas)
- {
- Rect oldWindRect;
- short hChange, vChange;
- OSErr err = noErr;
-
- SW_ASSERT(spriteWorldP != NULL && newWorldRectP != NULL);
-
- // Report error if newWorldRectP is larger than the size of the offscreen areas
- if ( SW_RECT_WIDTH((*newWorldRectP)) > SW_RECT_WIDTH(spriteWorldP->originalBackRect) ||
- SW_RECT_HEIGHT((*newWorldRectP)) > SW_RECT_HEIGHT(spriteWorldP->originalBackRect) )
- {
- err = kOutOfRangeErr;
- }
-
-
- if (err == noErr)
- {
- // Now we calculate the difference in size of old and new windRect
- oldWindRect = spriteWorldP->windRect;
- hChange = (oldWindRect.right - oldWindRect.left) -
- (newWorldRectP->right - newWorldRectP->left);
- vChange = (oldWindRect.bottom - oldWindRect.top) -
- (newWorldRectP->bottom - newWorldRectP->top);
-
- // Change the windRect
- spriteWorldP->windRect = *newWorldRectP;
-
- // Resize the visScrollRect
- SWResizeVisScrollRect(spriteWorldP,
- newWorldRectP->right - newWorldRectP->left,
- newWorldRectP->bottom - newWorldRectP->top);
-
- if (changeOffscreenAreas)
- {
- // Make offscreen areas think they are the same size as the new windRect
- spriteWorldP->workFrameP->frameRect.bottom -= vChange;
- spriteWorldP->workFrameP->frameRect.right -= hChange;
- spriteWorldP->backFrameP->frameRect.bottom -= vChange;
- spriteWorldP->backFrameP->frameRect.right -= hChange;
-
- // Update backRect as well
- spriteWorldP->backRect.bottom -= vChange;
- spriteWorldP->backRect.right -= hChange;
- }
-
- // Recalculate blitter data based on new windRect position
- SWWindowMoved(spriteWorldP);
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWRestoreWorldRect
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWRestoreWorldRect(SpriteWorldPtr spriteWorldP)
- {
- Rect originalWindRect = spriteWorldP->originalWindRect;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- // Restore everything to its original size
- spriteWorldP->windRect = originalWindRect;
- spriteWorldP->workFrameP->frameRect = spriteWorldP->originalBackRect;
- spriteWorldP->backFrameP->frameRect = spriteWorldP->originalBackRect;
- spriteWorldP->backRect = spriteWorldP->originalBackRect;
-
- // Resize the visScrollRect to match the originalWindRect
- SWResizeVisScrollRect(spriteWorldP,
- originalWindRect.right - originalWindRect.left,
- originalWindRect.bottom - originalWindRect.top);
-
- // Recalculate blitter data based on new windRect position
- SWWindowMoved(spriteWorldP);
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWindowMoved
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWindowMoved(SpriteWorldPtr spriteWorldP)
- {
- // Boolean needRedraw = false;
-
- SWWindowFrameMoved( spriteWorldP->windowFrameP, &spriteWorldP->windRect );
-
- /* Commented out the aligning code, since it doesn't seem to work everywhere ? :-(
-
- if ( SWAlignFrameToWindow( spriteWorldP->workFrameP, spriteWorldP->windowFrameP ) )
- needRedraw = true;
- if ( SWAlignFrameToWindow( spriteWorldP->backFrameP, spriteWorldP->windowFrameP ) )
- needRedraw = true;
- if ( spriteWorldP->extraBackFrameP != NULL )
- if ( SWAlignFrameToWindow( spriteWorldP->extraBackFrameP, spriteWorldP->windowFrameP ) )
- needRedraw = true;
-
- if ( needRedraw )
- {
- // update tiles
- if ( spriteWorldP->tilingIsOn )
- {
- SWResetTilingCache( spriteWorldP );
- SWDrawTilesInBackground( spriteWorldP );
- }
-
- // update work area
- SWSetPortToWindow( spriteWorldP );
- if ( EqualRect(&spriteWorldP->windRect,&spriteWorldP->offscreenScrollRect ) )
- SWUpdateSpriteWorld( spriteWorldP, false );
- else
- SWUpdateScrollingSpriteWorld( spriteWorldP, false );
- }
- */
-
-
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWWindowFrameMoved
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWWindowFrameMoved(
- FramePtr windowFrameP,
- Rect *frameRect)
- {
- GrafPtr savePort;
- Rect globalWorldRect,
- screenRect;
- GDHandle maxDevice;
-
- SW_ASSERT(windowFrameP != NULL);
- SW_ASSERT(windowFrameP->isFrameLocked);
-
- GetPort( &savePort );
-
- globalWorldRect = *frameRect;
- SetPort( (GrafPtr) windowFrameP->framePort );
- LocalToGlobal( &(topLeft(globalWorldRect)) );
- LocalToGlobal( &(botRight(globalWorldRect)) );
-
- maxDevice = GetMaxDevice(&globalWorldRect);
- screenRect = (*maxDevice)->gdRect;
-
- // Clip worldRect with screenRect
- if (globalWorldRect.top < screenRect.top)
- globalWorldRect.top = screenRect.top;
- if (globalWorldRect.bottom > screenRect.bottom)
- globalWorldRect.bottom = screenRect.bottom;
- if (globalWorldRect.left < screenRect.left)
- globalWorldRect.left = screenRect.left;
- if (globalWorldRect.right > screenRect.right)
- globalWorldRect.right = screenRect.right;
-
- // Convert global rect back to local rect
- GlobalToLocal( &(topLeft(globalWorldRect)) );
- GlobalToLocal( &(botRight(globalWorldRect)) );
-
- windowFrameP->frameRect = globalWorldRect;
-
- // frame blitter stuff needs to be re-calced, since things might have changed
- if ( windowFrameP->isFrameLocked )
- {
- SWUnlockWindowFrame( windowFrameP );
- SWLockWindowFrame( windowFrameP );
- }
-
- SetPort( savePort );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWUpdateWindow
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateWindow(
- SpriteWorldPtr spriteWorldP)
- {
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- SWSetPortToFrame( spriteWorldP->windowFrameP );
- spriteWorldP->numTilesChanged = 0;
-
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &spriteWorldP->visScrollRect,
- &spriteWorldP->windowFrameP->frameRect);
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- #pragma mark -
- ///--------------------------------------------------------------------------------------
- // SWUpdateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWUpdateSpriteWorld(
- SpriteWorldPtr spriteWorldP,
- Boolean updateWindow)
- {
- UpdateRectStructPtr curRectStructP,
- nextRectStructP;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- Rect tempRect;
- GWorldPtr holdGWorld;
- GDHandle holdGDH;
- short curTileLayer;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- GetGWorld( &holdGWorld, &holdGDH );
-
- gSWCurrentSpriteWorld = spriteWorldP;
-
- // Copy the background into the work area
- SWSetPortToFrame( spriteWorldP->workFrameP );
- (*spriteWorldP->offscreenDrawProc)(spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &spriteWorldP->backFrameP->frameRect,
- &spriteWorldP->workFrameP->frameRect);
-
- // Call the postEraseCallBack
- if (spriteWorldP->postEraseCallBack != NULL)
- (*spriteWorldP->postEraseCallBack)(spriteWorldP);
-
-
- // Build the current frame of the animation in the work area
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
- curTileLayer = 0;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- if (curSpriteLayerP->tileLayer > curTileLayer)
- curTileLayer = curSpriteLayerP->tileLayer;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- curSpriteP->tileDepth = curTileLayer;
-
- if (curSpriteP->isVisible)
- {
- gSWCurrentSpriteBeingDrawn = curSpriteP;
-
- // draw the sprite in the work area
- (*curSpriteP->frameDrawProc)(curSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &curSpriteP->curFrameP->frameRect,
- &curSpriteP->destFrameRect);
-
- gSWCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- curSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- tempRect = curSpriteP->destFrameRect;
-
- // Clip tempRect to visScrollRect
- if (tempRect.left < spriteWorldP->visScrollRect.left)
- tempRect.left = spriteWorldP->visScrollRect.left;
- if (tempRect.right > spriteWorldP->visScrollRect.right)
- tempRect.right = spriteWorldP->visScrollRect.right;
- if (tempRect.top < spriteWorldP->visScrollRect.top)
- tempRect.top = spriteWorldP->visScrollRect.top;
- if (tempRect.bottom > spriteWorldP->visScrollRect.bottom)
- tempRect.bottom = spriteWorldP->visScrollRect.bottom;
-
- SWDrawTilesAboveSprite(spriteWorldP, &tempRect, curSpriteP->tileDepth);
- }
-
- }
-
- // set the delta and last rect to the current rect
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- // this sprite no longer needs to be drawn
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- // Copy the work area into the window
- if (updateWindow)
- {
- SWSetPortToFrame( spriteWorldP->windowFrameP );
-
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &spriteWorldP->visScrollRect,
- &spriteWorldP->windowFrameP->frameRect);
- }
-
-
- // dispose of flagged background rects
- nextRectStructP = spriteWorldP->headUpdateRectP;
- while ( nextRectStructP != NULL )
- {
- curRectStructP = nextRectStructP;
- nextRectStructP = curRectStructP->nextRectStructP;
- DisposePtr( (Ptr)curRectStructP );
- }
- spriteWorldP->headUpdateRectP = NULL;
-
- spriteWorldP->numTilesChanged = 0;
-
- gSWCurrentSpriteWorld = NULL;
-
- SetGWorld( holdGWorld, holdGDH );
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWProcessSpriteWorld - IMPORTANT: if you ever change this function, change
- // SWProcessSpriteLayer to match this. This could call SWProcessSpriteLayer, but currently
- // the code is placed here directly to make it a little faster. Also, unlike
- // SWProcessSpriteLayer, this function does *not* process non-scrolling layers. So if this
- // called SWProcessSpriteLayer, we'd have to make sure it's a non-scrolling layer first.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- UnsignedWide curMicroseconds;
- register unsigned long millisecDifference;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP, nextSpriteP;
- register FramePtr newFrameP;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- gSWCurrentSpriteWorld = spriteWorldP;
-
- Microseconds( &curMicroseconds );
- // has hi long has rolled over?
- if ( curMicroseconds.hi > spriteWorldP->lastMicroseconds.hi )
- {
- millisecDifference =
- (0xffffffff - (spriteWorldP->lastMicroseconds.lo - curMicroseconds.lo))/1000;
- }
- else
- {
- millisecDifference = (curMicroseconds.lo - spriteWorldP->lastMicroseconds.lo)/1000;
- }
-
- if ( millisecDifference > 0 )
- {
- spriteWorldP->runningTimeCount += millisecDifference;
- spriteWorldP->lastMicroseconds.lo = curMicroseconds.lo;
- spriteWorldP->lastMicroseconds.hi = curMicroseconds.hi;
- }
-
- if ( (spriteWorldP->runningTimeCount - spriteWorldP->timeOfLastFrame >=
- spriteWorldP->fpsTimeInterval) )
- {
- spriteWorldP->frameHasOccurred = true;
- spriteWorldP->timeOfLastFrame = spriteWorldP->runningTimeCount;
- }
- else
- {
- spriteWorldP->frameHasOccurred = false;
- return;
- }
-
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWFindSpritesToBeRemoved( spriteWorldP );
- }
-
- // Call the tileChangeProc, if there is one
- if (spriteWorldP->tileChangeProc != NULL)
- {
- (*spriteWorldP->tileChangeProc)(spriteWorldP);
- }
-
- // Set this to false before entering the loop below.
- spriteWorldP->thereAreNonScrollingLayers = false;
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- if (curSpriteLayerP->layerIsNonScrolling)
- {
- spriteWorldP->thereAreNonScrollingLayers = true;
- }
- else if (!curSpriteLayerP->isPaused)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- nextSpriteP = curSpriteP->nextSpriteP;
-
- // is it time to advance the sprite’s frame?
- if ( curSpriteP->frameTimeInterval >= 0 &&
- (spriteWorldP->runningTimeCount - curSpriteP->timeOfLastFrameChange) >=
- curSpriteP->frameTimeInterval )
- {
- register long currentFrameIndex;
-
-
- curSpriteP->timeOfLastFrameChange = spriteWorldP->runningTimeCount;
-
- currentFrameIndex = curSpriteP->curFrameIndex;
- currentFrameIndex += curSpriteP->frameAdvance;
-
- if (currentFrameIndex < curSpriteP->firstFrameIndex)
- {
- if (curSpriteP->frameAdvanceMode == kSWWrapAroundMode)
- {
- // wrap to the last frame
- currentFrameIndex = curSpriteP->lastFrameIndex;
- }
- else // curSpriteP->frameAdvanceMode == kSWPatrollingMode
- {
- // change direction and set index to what it should be
- curSpriteP->frameAdvance = -curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- }
- }
- else if (currentFrameIndex > curSpriteP->lastFrameIndex)
- {
- if (curSpriteP->frameAdvanceMode == kSWWrapAroundMode)
- {
- // wrap to the first frame
- currentFrameIndex = curSpriteP->firstFrameIndex;
- }
- else // curSpriteP->frameAdvanceMode == kSWPatrollingMode
- {
- // change direction and set index to what it should be
- curSpriteP->frameAdvance = -curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- }
- }
-
- curSpriteP->curFrameIndex = currentFrameIndex;
-
-
- // is there a frame callback?
- if (curSpriteP->frameChangeProc != NULL)
- {
- // get new frame
- newFrameP = curSpriteP->frameArray[currentFrameIndex];
-
- // call it
- (*curSpriteP->frameChangeProc)(curSpriteP, newFrameP,
- &curSpriteP->curFrameIndex);
-
- // make sure the new frame index is in range
- if (curSpriteP->curFrameIndex < 0)
- {
- curSpriteP->curFrameIndex = 0;
- }
- else if (curSpriteP->curFrameIndex >= curSpriteP->maxFrames)
- {
- curSpriteP->curFrameIndex = curSpriteP->maxFrames - 1;
- }
- }
-
- // change the frame
- newFrameP = curSpriteP->frameArray[curSpriteP->curFrameIndex];
-
- // has the frame actually changed?
- if (curSpriteP->curFrameP != newFrameP)
- {
- SWSetCurrentFrameIndex(curSpriteP, curSpriteP->curFrameIndex);
- }
- }
-
- // is it time to move the sprite?
- if ( curSpriteP->moveTimeInterval >= 0 &&
- (spriteWorldP->runningTimeCount - curSpriteP->timeOfLastMove) >=
- curSpriteP->moveTimeInterval )
- {
- curSpriteP->timeOfLastMove = spriteWorldP->runningTimeCount;
-
- // is there a movement callback?
- if (curSpriteP->spriteMoveProc != NULL)
- {
- (*curSpriteP->spriteMoveProc)(curSpriteP);
- }
- }
- curSpriteP = nextSpriteP;
- }
- }
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- gSWCurrentSpriteWorld = NULL;
-
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWProcessNonScrollingLayers - processes those layers in a scrolling world that need
- // to be moved after the visScrollRect is moved. Also ensures each Sprite's coordinate
- // system remains local to the window, not to the virtual world.
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessNonScrollingLayers(
- SpriteWorldPtr spriteWorldP)
- {
- register SpriteLayerPtr curSpriteLayerP;
-
- // Exit if there's no work for us to do.
- if (spriteWorldP->thereAreNonScrollingLayers == false)
- return;
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- // Process any non-scrolling layers
- if (curSpriteLayerP->layerIsNonScrolling)
- {
- SWProcessSpriteLayer(spriteWorldP, curSpriteLayerP);
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- // We've finished processing all non-scrolling layers for this frame.
- spriteWorldP->thereAreNonScrollingLayers = false;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWProcessSpriteLayer
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWProcessSpriteLayer(
- SpriteWorldPtr spriteWorldP,
- SpriteLayerPtr curSpriteLayerP)
- {
- register SpritePtr curSpriteP, nextSpriteP;
- register FramePtr newFrameP;
-
- if (!curSpriteLayerP->isPaused)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- nextSpriteP = curSpriteP->nextSpriteP;
-
- // is it time to advance the sprite’s frame?
- if ( curSpriteP->frameTimeInterval >= 0 &&
- (spriteWorldP->runningTimeCount - curSpriteP->timeOfLastFrameChange) >=
- curSpriteP->frameTimeInterval )
- {
- register long currentFrameIndex;
-
-
- curSpriteP->timeOfLastFrameChange = spriteWorldP->runningTimeCount;
-
- currentFrameIndex = curSpriteP->curFrameIndex;
- currentFrameIndex += curSpriteP->frameAdvance;
-
- if (currentFrameIndex < curSpriteP->firstFrameIndex)
- {
- if (curSpriteP->frameAdvanceMode == kSWWrapAroundMode)
- {
- // wrap to the last frame
- currentFrameIndex = curSpriteP->lastFrameIndex;
- }
- else // curSpriteP->frameAdvanceMode == kSWPatrollingMode
- {
- // change direction and set index to what it should be
- curSpriteP->frameAdvance = -curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- }
- }
- else if (currentFrameIndex > curSpriteP->lastFrameIndex)
- {
- if (curSpriteP->frameAdvanceMode == kSWWrapAroundMode)
- {
- // wrap to the first frame
- currentFrameIndex = curSpriteP->firstFrameIndex;
- }
- else // curSpriteP->frameAdvanceMode == kSWPatrollingMode
- {
- // change direction and set index to what it should be
- curSpriteP->frameAdvance = -curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- currentFrameIndex += curSpriteP->frameAdvance;
- }
- }
-
- curSpriteP->curFrameIndex = currentFrameIndex;
-
-
- // is there a frame callback?
- if (curSpriteP->frameChangeProc != NULL)
- {
- // get new frame
- newFrameP = curSpriteP->frameArray[currentFrameIndex];
-
- // call it
- (*curSpriteP->frameChangeProc)(curSpriteP, newFrameP,
- &curSpriteP->curFrameIndex);
-
- // make sure the new frame index is in range
- if (curSpriteP->curFrameIndex < 0)
- {
- curSpriteP->curFrameIndex = 0;
- }
- else if (curSpriteP->curFrameIndex >= curSpriteP->maxFrames)
- {
- curSpriteP->curFrameIndex = curSpriteP->maxFrames - 1;
- }
- }
-
- // change the frame
- newFrameP = curSpriteP->frameArray[curSpriteP->curFrameIndex];
-
- // has the frame actually changed?
- if (curSpriteP->curFrameP != newFrameP)
- {
- SWSetCurrentFrameIndex(curSpriteP, curSpriteP->curFrameIndex);
- }
- }
-
- // is it time to move the sprite?
- if ( curSpriteP->moveTimeInterval >= 0 &&
- (spriteWorldP->runningTimeCount - curSpriteP->timeOfLastMove) >=
- curSpriteP->moveTimeInterval )
- {
- curSpriteP->timeOfLastMove = spriteWorldP->runningTimeCount;
-
- // is there a movement callback?
- if (curSpriteP->spriteMoveProc != NULL)
- {
- (*curSpriteP->spriteMoveProc)(curSpriteP);
- }
- }
-
- curSpriteP = nextSpriteP;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWAnimateSpriteWorld
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWAnimateSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- UpdateRectStructPtr curRectStructP,
- nextRectStructP;
- register SpriteLayerPtr curSpriteLayerP;
- register SpritePtr curSpriteP;
- SpritePtr headActiveSpriteP = NULL; // Tail of active sprite list
- SpritePtr headIdleSpriteP = NULL; // Tail of idle sprite list
- SpritePtr curActiveSpriteP = NULL;
- SpritePtr curIdleSpriteP = NULL;
- Rect screenDestRect;
- Rect *changedRectP;
- short index, curTileLayer;
-
- SW_ASSERT(spriteWorldP != NULL);
- SW_ASSERT(spriteWorldP->backFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->workFrameP->isFrameLocked);
- SW_ASSERT(spriteWorldP->windowFrameP->isFrameLocked);
-
- gSWCurrentSpriteWorld = spriteWorldP;
-
- if (!spriteWorldP->frameHasOccurred)
- return;
-
- // Add the deadSpriteLayer if there are any Sprites in it, so they get erased.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWAddSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
- // the current port should be the one in which we are drawing
- SWSetPortToFrame( spriteWorldP->workFrameP );
-
- //-----------------erase the sprites--------------------
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
- curTileLayer = 0;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- if (curSpriteLayerP->tileLayer > curTileLayer)
- curTileLayer = curSpriteLayerP->tileLayer;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- SW_ASSERT(curSpriteP->curFrameP->isFrameLocked);
- curSpriteP->tileDepth = curTileLayer;
-
- if ((curSpriteP->needsToBeDrawn && curSpriteP->isVisible) ||
- (curSpriteP->needsToBeErased && !curSpriteP->isVisible))
- {
- // Add sprite to active sprite list
- if (headActiveSpriteP == NULL)
- headActiveSpriteP = curSpriteP;
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = curSpriteP;
-
- curActiveSpriteP = curSpriteP;
-
- // union last rect and current rect
- // this way is much faster than UnionRect
- curSpriteP->deltaFrameRect.top =
- SW_MIN(curSpriteP->oldFrameRect.top, curSpriteP->destFrameRect.top);
- curSpriteP->deltaFrameRect.left =
- SW_MIN(curSpriteP->oldFrameRect.left, curSpriteP->destFrameRect.left);
- curSpriteP->deltaFrameRect.bottom =
- SW_MAX(curSpriteP->oldFrameRect.bottom, curSpriteP->destFrameRect.bottom);
- curSpriteP->deltaFrameRect.right =
- SW_MAX(curSpriteP->oldFrameRect.right, curSpriteP->destFrameRect.right);
- {
- short temp;
-
- // align the left edge to long word boundary
- curSpriteP->deltaFrameRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = curSpriteP->deltaFrameRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- curSpriteP->deltaFrameRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
-
- // align the left edge to long word boundary
- curSpriteP->oldFrameRect.left &=
- (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = curSpriteP->oldFrameRect.right &
- spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- curSpriteP->oldFrameRect.right +=
- (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
- }
-
- // copy the back drop piece
- (*spriteWorldP->offscreenDrawProc)(
- spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &curSpriteP->oldFrameRect,
- &curSpriteP->oldFrameRect);
- }
- else if (curSpriteP->isVisible)
- {
- // Add sprite to idle sprite list
- if (headIdleSpriteP == NULL)
- headIdleSpriteP = curSpriteP;
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = curSpriteP;
-
- curIdleSpriteP = curSpriteP;
- }
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
- if (curActiveSpriteP != NULL)
- curActiveSpriteP->nextActiveSpriteP = NULL;
-
- if (curIdleSpriteP != NULL)
- curIdleSpriteP->nextIdleSpriteP = NULL;
-
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- (*spriteWorldP->offscreenDrawProc)(
- spriteWorldP->backFrameP,
- spriteWorldP->workFrameP,
- &curRectStructP->updateRect,
- &curRectStructP->updateRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Redraw idle sprites that were erased by a tile
- if (spriteWorldP->numTilesChanged > 0)
- SWCheckIdleSpritesWithTiles(spriteWorldP, headIdleSpriteP);
-
- // Redraw idle sprites that were erased by an updateRect
- if (spriteWorldP->headUpdateRectP != NULL)
- SWCheckIdleSpritesWithRects(spriteWorldP, headIdleSpriteP);
-
- // Call the postEraseCallBack
- if (spriteWorldP->postEraseCallBack != NULL)
- (*spriteWorldP->postEraseCallBack)(spriteWorldP);
-
-
- //-----------------draw the sprites--------------------
-
- curSpriteLayerP = spriteWorldP->headSpriteLayerP;
-
- // iterate through the layers in this world
- while (curSpriteLayerP != NULL)
- {
- curSpriteP = curSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in this layer
- while (curSpriteP != NULL)
- {
- if (curSpriteP->isVisible)
- {
- if (curSpriteP->needsToBeDrawn)
- {
- gSWCurrentSpriteBeingDrawn = curSpriteP;
-
- // draw the sprite in the work area
- (*curSpriteP->frameDrawProc)(
- curSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &curSpriteP->curFrameP->frameRect,
- &curSpriteP->destFrameRect);
-
- gSWCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- curSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- screenDestRect = curSpriteP->destFrameRect;
-
- // Clip screenDestRect to visScrollRect
- if (screenDestRect.left < spriteWorldP->visScrollRect.left)
- screenDestRect.left = spriteWorldP->visScrollRect.left;
- if (screenDestRect.right > spriteWorldP->visScrollRect.right)
- screenDestRect.right = spriteWorldP->visScrollRect.right;
- if (screenDestRect.top < spriteWorldP->visScrollRect.top)
- screenDestRect.top = spriteWorldP->visScrollRect.top;
- if (screenDestRect.bottom > spriteWorldP->visScrollRect.bottom)
- screenDestRect.bottom = spriteWorldP->visScrollRect.bottom;
-
- SWDrawTilesAboveSprite(spriteWorldP, &screenDestRect, curSpriteP->tileDepth);
- }
- }
- else
- {
- SWCheckIdleSpriteOverlap(spriteWorldP, curSpriteP, headActiveSpriteP);
- }
- }
-
- curSpriteP = curSpriteP->nextSpriteP;
- }
-
- curSpriteLayerP = curSpriteLayerP->nextSpriteLayerP;
- }
-
-
- // Call the postDrawCallBack
- if (spriteWorldP->postDrawCallBack != NULL)
- (*spriteWorldP->postDrawCallBack)(spriteWorldP);
-
-
- //-----------------update the screen--------------------
-
- // the current port should be the one in which we are drawing
- SWSetPortToFrame( spriteWorldP->windowFrameP );
-
- // wait for the VBL
- if ( spriteWorldP->usingVBL )
- {
- spriteWorldP->vblTaskRec.hasVBLFired = false;
- while ( !spriteWorldP->vblTaskRec.hasVBLFired )
- {}
- }
-
- curSpriteP = headActiveSpriteP;
-
- // Has a custom worldRect been used? (If so, sprites need offsetting)
- if (spriteWorldP->windRect.left || spriteWorldP->windRect.top)
- {
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- screenDestRect = curRectStructP->updateRect;
- screenDestRect.left += spriteWorldP->windRect.left;
- screenDestRect.right += spriteWorldP->windRect.left;
- screenDestRect.top += spriteWorldP->windRect.top;
- screenDestRect.bottom += spriteWorldP->windRect.top;
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curRectStructP->updateRect,
- &screenDestRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Update on screen the tiles that have changed
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- screenDestRect = *changedRectP;
-
- // offset dest rect for screen
- screenDestRect.left += spriteWorldP->windRect.left;
- screenDestRect.right += spriteWorldP->windRect.left;
- screenDestRect.top += spriteWorldP->windRect.top;
- screenDestRect.bottom += spriteWorldP->windRect.top;
-
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP, changedRectP, &screenDestRect);
- }
-
-
- // update the sprites on the screen
- while (curSpriteP != NULL)
- {
- // offset the sprite's delta rect for the screen
- screenDestRect = curSpriteP->deltaFrameRect;
-
- screenDestRect.left += spriteWorldP->windRect.left;
- screenDestRect.right += spriteWorldP->windRect.left;
- screenDestRect.top += spriteWorldP->windRect.top;
- screenDestRect.bottom += spriteWorldP->windRect.top;
-
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curSpriteP->deltaFrameRect,
- &screenDestRect);
-
-
- // set the delta and last rect to the current rect
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- // this sprite no longer needs to be drawn
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextActiveSpriteP;
- }
- }
- else
- {
- // update flagged background rects
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP != NULL )
- {
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curRectStructP->updateRect,
- &curRectStructP->updateRect);
- curRectStructP = curRectStructP->nextRectStructP;
- }
-
- // Update on screen the tiles that have changed
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- (*spriteWorldP->screenDrawProc)(spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP, changedRectP, changedRectP);
- }
-
-
- // update the sprites on the screen
- while (curSpriteP != NULL)
- {
- (*spriteWorldP->screenDrawProc)(
- spriteWorldP->workFrameP,
- spriteWorldP->windowFrameP,
- &curSpriteP->deltaFrameRect,
- &curSpriteP->deltaFrameRect);
-
-
- // set the delta and last rect to the current rect
- curSpriteP->deltaFrameRect = curSpriteP->destFrameRect;
- curSpriteP->oldFrameRect = curSpriteP->destFrameRect;
-
- // this sprite no longer needs to be drawn
- curSpriteP->needsToBeDrawn = false;
- curSpriteP->needsToBeErased = false;
-
- curSpriteP = curSpriteP->nextActiveSpriteP;
- }
- }
-
- // dispose of flagged background rects
- nextRectStructP = spriteWorldP->headUpdateRectP;
- while ( nextRectStructP != NULL )
- {
- curRectStructP = nextRectStructP;
- nextRectStructP = curRectStructP->nextRectStructP;
- DisposePtr( (Ptr)curRectStructP );
- }
- spriteWorldP->headUpdateRectP = NULL;
-
- spriteWorldP->numTilesChanged = 0;
-
- // Remove the deadSpriteLayer if we added it earlier.
- if ( spriteWorldP->deadSpriteLayerP->headSpriteP != NULL )
- {
- SWRemoveSpriteLayer(spriteWorldP, spriteWorldP->deadSpriteLayerP);
- }
-
- gSWCurrentSpriteWorld = NULL;
-
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckIdleSpriteOverlap
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckIdleSpriteOverlap(
- SpriteWorldPtr spriteWorldP,
- SpritePtr idleSpriteP,
- SpritePtr headActiveSpriteP)
- {
- register SpritePtr activeSpriteP = headActiveSpriteP;
- Rect srcSectRect, dstSectRect;
-
- // iterate through the active sprites
- while (activeSpriteP != NULL)
- {
- // do the sprites overlap?
- if ((idleSpriteP->oldFrameRect.top < activeSpriteP->deltaFrameRect.bottom) &&
- (idleSpriteP->oldFrameRect.bottom > activeSpriteP->deltaFrameRect.top) &&
- (idleSpriteP->oldFrameRect.left < activeSpriteP->deltaFrameRect.right) &&
- (idleSpriteP->oldFrameRect.right > activeSpriteP->deltaFrameRect.left))
- {
- // calculate the intersection between the idle sprite's destination
- // rect, and the active sprite's delta rect
- dstSectRect.left =
- SW_MAX(idleSpriteP->destFrameRect.left, activeSpriteP->deltaFrameRect.left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->destFrameRect.top, activeSpriteP->deltaFrameRect.top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->destFrameRect.right, activeSpriteP->deltaFrameRect.right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->destFrameRect.bottom, activeSpriteP->deltaFrameRect.bottom);
-
- srcSectRect = idleSpriteP->curFrameP->frameRect;
-
- srcSectRect.left += (dstSectRect.left - idleSpriteP->destFrameRect.left);
- srcSectRect.top += (dstSectRect.top - idleSpriteP->destFrameRect.top);
- srcSectRect.right -= (idleSpriteP->destFrameRect.right - dstSectRect.right);
- srcSectRect.bottom -= (idleSpriteP->destFrameRect.bottom - dstSectRect.bottom);
-
-
- // copy a piece of the sprite image onto the workFrame
-
- gSWCurrentSpriteBeingDrawn = idleSpriteP;
-
- (*idleSpriteP->frameDrawProc)(
- idleSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &srcSectRect,
- &dstSectRect);
-
-
- gSWCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- idleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- // Clip dstSectRect to visScrollRect
- if (dstSectRect.left < spriteWorldP->visScrollRect.left)
- dstSectRect.left = spriteWorldP->visScrollRect.left;
- if (dstSectRect.right > spriteWorldP->visScrollRect.right)
- dstSectRect.right = spriteWorldP->visScrollRect.right;
- if (dstSectRect.top < spriteWorldP->visScrollRect.top)
- dstSectRect.top = spriteWorldP->visScrollRect.top;
- if (dstSectRect.bottom > spriteWorldP->visScrollRect.bottom)
- dstSectRect.bottom = spriteWorldP->visScrollRect.bottom;
-
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect, idleSpriteP->tileDepth);
- }
- }
-
- activeSpriteP = activeSpriteP->nextActiveSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckIdleSpritesWithTiles - redraw sprites erased by tiles that changed
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckIdleSpritesWithTiles(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP)
- {
- Rect srcSectRect, dstSectRect;
- register SpritePtr idleSpriteP;
- short srcHorizOffset;
- short srcVertOffset;
- Rect *changedRectP;
- short index;
-
-
- // Cycle through the changedTiles array of rects
- changedRectP = spriteWorldP->changedTiles;
- for (index = 0; index < spriteWorldP->numTilesChanged; index++, changedRectP++)
- {
- idleSpriteP = headIdleSpriteP;
-
- // iterate through the idle sprites
- while (idleSpriteP != NULL)
- {
- // does the idle sprite overlap the changedRect?
- if ((idleSpriteP->oldFrameRect.top < changedRectP->bottom) &&
- (idleSpriteP->oldFrameRect.bottom > changedRectP->top) &&
- (idleSpriteP->oldFrameRect.left < changedRectP->right) &&
- (idleSpriteP->oldFrameRect.right > changedRectP->left))
- {
- // calculate the intersection between the idle
- // sprite's rect and the changedRectP
- dstSectRect.left =
- SW_MAX(idleSpriteP->oldFrameRect.left, changedRectP->left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->oldFrameRect.top, changedRectP->top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->oldFrameRect.right, changedRectP->right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->oldFrameRect.bottom, changedRectP->bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
-
- // Copy a piece of the sprite image onto the back drop piece
-
- gSWCurrentSpriteBeingDrawn = idleSpriteP;
-
- (*idleSpriteP->frameDrawProc)(
- idleSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &srcSectRect,
- &dstSectRect);
-
- gSWCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- idleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect, idleSpriteP->tileDepth);
- }
- }
-
- idleSpriteP = idleSpriteP->nextIdleSpriteP;
- }
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWCheckIdleSpritesWithRects - redraw sprites erased by updateRects
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWCheckIdleSpritesWithRects(
- SpriteWorldPtr spriteWorldP,
- SpritePtr headIdleSpriteP)
- {
- UpdateRectStructPtr curRectStructP;
- register SpritePtr idleSpriteP;
- Rect srcSectRect, dstSectRect;
- short srcHorizOffset;
- short srcVertOffset;
- Rect *changedRectP;
-
-
- curRectStructP = spriteWorldP->headUpdateRectP;
-
- while (curRectStructP != NULL)
- {
- changedRectP = &curRectStructP->updateRect;
- idleSpriteP = headIdleSpriteP;
-
- // iterate through the idle sprites
- while (idleSpriteP != NULL)
- {
- // does the idle sprite overlap the changedRect?
- if ((idleSpriteP->oldFrameRect.top < changedRectP->bottom) &&
- (idleSpriteP->oldFrameRect.bottom > changedRectP->top) &&
- (idleSpriteP->oldFrameRect.left < changedRectP->right) &&
- (idleSpriteP->oldFrameRect.right > changedRectP->left))
- {
- // calculate the intersection between the idle
- // sprite's rect and the changedRectP
- dstSectRect.left =
- SW_MAX(idleSpriteP->oldFrameRect.left, changedRectP->left);
- dstSectRect.top =
- SW_MAX(idleSpriteP->oldFrameRect.top, changedRectP->top);
- dstSectRect.right =
- SW_MIN(idleSpriteP->oldFrameRect.right, changedRectP->right);
- dstSectRect.bottom =
- SW_MIN(idleSpriteP->oldFrameRect.bottom, changedRectP->bottom);
-
- // Calculate the source rect
- srcSectRect = dstSectRect;
-
- srcHorizOffset = idleSpriteP->curFrameP->frameRect.left;
- srcVertOffset = idleSpriteP->curFrameP->frameRect.top;
-
- srcSectRect.left -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.right -= (idleSpriteP->oldFrameRect.left - srcHorizOffset);
- srcSectRect.top -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
- srcSectRect.bottom -= (idleSpriteP->oldFrameRect.top - srcVertOffset);
-
- // Copy a piece of the sprite image onto the back drop piece
-
- gSWCurrentSpriteBeingDrawn = idleSpriteP;
-
- (*idleSpriteP->frameDrawProc)(
- idleSpriteP->curFrameP,
- spriteWorldP->workFrameP,
- &srcSectRect,
- &dstSectRect);
-
- gSWCurrentSpriteBeingDrawn = NULL;
-
- if (spriteWorldP->tilingIsOn &&
- idleSpriteP->tileDepth <= spriteWorldP->lastActiveTileLayer)
- {
- dstSectRect.top += spriteWorldP->vertScrollRectOffset;
- dstSectRect.bottom += spriteWorldP->vertScrollRectOffset;
- dstSectRect.left += spriteWorldP->horizScrollRectOffset;
- dstSectRect.right += spriteWorldP->horizScrollRectOffset;
- SWDrawTilesAboveSprite(spriteWorldP, &dstSectRect, idleSpriteP->tileDepth);
- }
- }
-
- idleSpriteP = idleSpriteP->nextIdleSpriteP;
- }
-
- curRectStructP = curRectStructP->nextRectStructP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFindSpritesToBeRemoved
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWFindSpritesToBeRemoved(
- SpriteWorldPtr spriteWorldP )
- {
- SpritePtr curSpriteP, nextSpriteP;
-
- curSpriteP = spriteWorldP->deadSpriteLayerP->headSpriteP;
-
- // iterate through the sprites in the deadSpriteLayerP
- while (curSpriteP != NULL)
- {
- nextSpriteP = curSpriteP->nextSpriteP;
-
- // all the Sprites here should need removing...
- SW_ASSERT(curSpriteP->spriteRemoval != kSWDontRemoveSprite);
-
- // has this sprite been erased by SWAnimate?
- if (curSpriteP->needsToBeErased == false)
- {
- // if so, we can safely remove it from its layer
- SWRemoveSprite(curSpriteP);
-
- // do we want to dispose of this sprite too?
- if (curSpriteP->spriteRemoval == kSWRemoveAndDisposeSprite)
- SWDisposeSprite(&curSpriteP);
- else
- curSpriteP->spriteRemoval = kSWDontRemoveSprite; // We're done
- }
-
- curSpriteP = nextSpriteP;
- }
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFlagRectAsChanged
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFlagRectAsChanged(
- SpriteWorldPtr spriteWorldP,
- Rect* theChangedRect)
- {
- UpdateRectStructPtr curRectStructP,
- newUpdateRectP;
- short temp;
- OSErr err = noErr;
-
- // align the left edge to long word boundary
- theChangedRect->left &= (spriteWorldP->workFrameP->leftAlignFactor);
-
- // align the right edge to long word boundary
- temp = theChangedRect->right & spriteWorldP->workFrameP->rightAlignFactor;
- if (temp != 0)
- {
- theChangedRect->right += (spriteWorldP->workFrameP->rightAlignFactor + 1) - temp;
- }
-
- newUpdateRectP = (UpdateRectStructPtr)NewPtr(sizeof(UpdateRectStruct));
- if ( newUpdateRectP != NULL )
- {
- newUpdateRectP->updateRect = *theChangedRect;
- newUpdateRectP->nextRectStructP = NULL;
-
- if ( spriteWorldP->headUpdateRectP == NULL )
- {
- spriteWorldP->headUpdateRectP = newUpdateRectP;
- }
- else
- {
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP->nextRectStructP != NULL )
- {
- curRectStructP = curRectStructP->nextRectStructP;
- }
- curRectStructP->nextRectStructP = newUpdateRectP;
- }
- }
- else
- {
- err = MemError();
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWFlagScrollingRectAsChanged - same as SWFlagRectAsChanged, minus alignment code
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWFlagScrollingRectAsChanged(
- SpriteWorldPtr spriteWorldP,
- Rect* theChangedRect)
- {
- UpdateRectStructPtr curRectStructP,
- newUpdateRectP;
- OSErr err = noErr;
-
-
- newUpdateRectP = (UpdateRectStructPtr)NewPtr(sizeof(UpdateRectStruct));
- if ( newUpdateRectP != NULL )
- {
- newUpdateRectP->updateRect = *theChangedRect;
- newUpdateRectP->nextRectStructP = NULL;
-
- if ( spriteWorldP->headUpdateRectP == NULL )
- {
- spriteWorldP->headUpdateRectP = newUpdateRectP;
- }
- else
- {
- curRectStructP = spriteWorldP->headUpdateRectP;
- while ( curRectStructP->nextRectStructP != NULL )
- {
- curRectStructP = curRectStructP->nextRectStructP;
- }
- curRectStructP->nextRectStructP = newUpdateRectP;
- }
- }
- else
- {
- err = MemError();
- }
-
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSyncSpriteWorldToVBL
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC OSErr SWSyncSpriteWorldToVBL(
- SpriteWorldPtr spriteWorldP,
- Boolean syncingOn)
- {
- OSErr err = noErr;
- AuxDCEHandle mainDCE;
-
- SW_ASSERT(spriteWorldP != NULL);
-
- if ( syncingOn )
- {
- if ( !spriteWorldP->usingVBL )
- {
- *((VBLUPP*)&spriteWorldP->vblTaskRec.myVBLTask.vblAddr) =
- NewVBLProc((ProcPtr)SWVBLTask);
- spriteWorldP->vblTaskRec.myVBLTask.qType = vType;
- spriteWorldP->vblTaskRec.myVBLTask.vblCount = 1;
- spriteWorldP->vblTaskRec.hasVBLFired = false;
-
- // insert the task into the VBL queue
- mainDCE = (AuxDCEHandle)GetDCtlEntry((**spriteWorldP->mainSWGDH).gdRefNum);
- err = SlotVInstall( (QElemPtr) &spriteWorldP->vblTaskRec.myVBLTask,
- (**mainDCE).dCtlSlot );
- if ( err == noErr )
- {
- spriteWorldP->usingVBL = true;
- }
- }
- }
- else
- {
- if ( spriteWorldP->usingVBL )
- {
- mainDCE = (AuxDCEHandle)GetDCtlEntry((**spriteWorldP->mainSWGDH).gdRefNum);
- err = SlotVRemove( (QElemPtr) &spriteWorldP->vblTaskRec.myVBLTask,
- (**mainDCE).dCtlSlot );
- spriteWorldP->vblTaskRec.hasVBLFired = true;
- spriteWorldP->usingVBL = false;
- DisposeRoutineDescriptor(spriteWorldP->vblTaskRec.myVBLTask.vblAddr);
- }
- }
-
- SWSetStickyIfError( err );
- return err;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWVBLTask
- ///--------------------------------------------------------------------------------------
-
- #if !GENERATINGCFM
- extern VBLTaskRecPtr GetVBLRec(void)
- = 0x2008; /* MOVE.L A0,D0 */
- #endif
-
- #if GENERATINGCFM
- void SWVBLTask(VBLTaskRecPtr vblTaskPtr)
- {
- vblTaskPtr->hasVBLFired = true;
-
- // Reset vblCount so that this procedure executes again
- vblTaskPtr->myVBLTask.vblCount = 1;
- }
- #else
- void SWVBLTask( void )
- {
- VBLTaskRecPtr vblTaskPtr;
-
- vblTaskPtr = (VBLTaskRecPtr) GetVBLRec();
- vblTaskPtr->hasVBLFired = true;
-
- // Reset vblCount so that this procedure executes again
- vblTaskPtr->myVBLTask.vblCount = 1;
- }
- #endif
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetCleanUpSpriteWorld - call this if you want FatalError() or SWAssertFail() to call
- // SWSyncSpriteWorldToVBL with a value of false for your SpriteWorld before it calls
- // ExitToShell. You pass a pointer to the SpriteWorld you want to be "cleaned up".
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetCleanUpSpriteWorld(
- SpriteWorldPtr spriteWorldP)
- {
- gSWCleanUpSpriteWorldP = spriteWorldP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWSetCleanUpFunction - installs a callback that is called whenever a fatal error or
- // assertion failure occurrs. Very useful for fading the screen back in, or doing any
- // other important tasks that must be done before quitting when a fatal error occurrs.
- // Your callback must be of this format: void MyCallBack(void).
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC void SWSetCleanUpFunction(
- CleanUpCallBackPtr callBackP)
- {
- gSWCleanUpCallBackP = callBackP;
- }
-
-
- ///--------------------------------------------------------------------------------------
- // SWGetSpriteWorldVersion - use the following in the 5th digit from the left:
- //
- // developStage = 0x20,
- // alphaStage = 0x40,
- // betaStage = 0x60,
- // finalStage = 0x80
- ///--------------------------------------------------------------------------------------
-
- SW_FUNC unsigned long SWGetSpriteWorldVersion(void)
- {
- return 0x02318000; // i.e. 0x02306003 would be "2.3 beta 3"
- }
-